home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Microsoft Multimedia Viewer How-To CD
/
Microsoft Multimedia Viewer How-To CD.iso
/
mvsample
/
progsamp
/
katasrch
/
katasrch.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-21
|
26KB
|
940 lines
#include <windows.h>
#include <viewer.h>
#include <stdlib.h>
#include "katasrch.h"
#include "mvbtask.h"
#include "results.h"
HANDLE ghModule = NULL;
PSTR szTitleSearch = "Search";
PSTR szTitleResults = "Topics Found";
/************************************************************************
* LibMain: Initialization function for the DLL
*
* - Initialize Results list, which keeps track of Topics Found windows
* - Store DLL module handle in global variable
* - Register Results window class
*
************************************************************************/
int CALLBACK LibMain(
HINSTANCE hinst, // handle of library instance
WORD wDataSeg, // library data segment
WORD cbHeap, // default heap size
LPSTR lpszCmdLine ) // command-line arguments
{
// Save the module handle
ghModule = hinst;
if(cbHeap)
UnlockData(0);
// Initialize the tasks list
InitTasks();
return 1;
}
/**************************************************************************
* GetDialogFont
*
* Creates the font used in search dialog box and results window.
**************************************************************************/
HFONT GetDialogFont(HWND hwnd)
{
HDC hdc = GetDC(hwnd);
HFONT hfont;
PLOGFONT plf = (PLOGFONT)LocalAlloc(LPTR, sizeof(LOGFONT));
plf->lfWeight = FW_BOLD;
plf->lfHeight = -MulDiv(8, GetDeviceCaps(hdc, LOGPIXELSY), 72);
lstrcpy(plf->lfFaceName, "MS Sans Serif");
hfont = CreateFontIndirect(plf);
LocalFree((HLOCAL) plf);
ReleaseDC(hwnd, hdc);
return hfont;
}
/**************************************************************************
* InitViewerInfo
*
* Initializes all the Viewer instance information needed by the search
* DLL.
*
* Returns zero if successful or an error code if unsuccessful.
**************************************************************************/
int InitViewerInfo(
LPVWRINFO lpVwrInfo, // Block of Viewer instance data
HWND hwndViewer, // Viewer window handle
LPSTR lpszTitle) // Title filename
{
// Store MVB filename
if(lpVwrInfo->szMVB[0] == '\0')
lstrcpy(lpVwrInfo->szMVB, lpszTitle);
// Register window message for identifying Results dialog
// to Viewer
if(lpVwrInfo->uiWMRegDlg == NULL)
lpVwrInfo->uiWMRegDlg = RegisterWindowMessage("MS_VWRSRCHRESDLG");
// Record Viewer handle
if(lpVwrInfo->vwr == NULL)
{
lpVwrInfo->hwndViewer = hwndViewer;
lpVwrInfo->vwr = VwrFromHwnd(hwndViewer);
if(lpVwrInfo->vwr == NULL)
return KSERR_NOVWR;
}
// Get a title handle
if(lpVwrInfo->htitle == NULL)
{
lpVwrInfo->htitle = TitleOpen(lpszTitle);
if(lpVwrInfo->htitle == NULL)
return KSERR_CANTOPENTITLE;
}
// Get our dialog-box font
if(lpVwrInfo->hfontDlg == NULL)
lpVwrInfo->hfontDlg = GetDialogFont(hwndViewer);
return 0;
}
/**************************************************************************
* DoSearchDialog
*
* Entry-point function for search interface. This function retrieves and
* stores information needed during the search, displays the
* search dialog box, and then displays the Results dialog box if the
* search was performed.
*
* Register with: RegisterRoutine("katasrch","DoSearchDialog","US")
* Call with: DoSearchDialog(hwndApp,qchPath)
*
**************************************************************************/
void WINAPI DoSearchDialog(
DWORD dwHwndViewer, // LOWORD has the Viewer window handle
LPSTR lpszTitle) // Title filename
{
LPVWRINFO lpVwrInfo;
HWND hwndViewer = LOWORD(dwHwndViewer);
int iRet;
RECT rc;
// Get the task data
lpVwrInfo = GetTaskData(GetCurrentTask());
if(lpVwrInfo == NULL)
{
ShowMessage(hwndViewer, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
return;
}
// Initialize the task-information structure
iRet = InitViewerInfo(lpVwrInfo, hwndViewer, lpszTitle);
if(iRet)
{
ShowMessage(hwndViewer, iRet, MB_ICONEXCLAMATION);
return;
}
// Display the Search dialog box
iRet = DialogBoxParam(ghModule, MAKEINTRESOURCE(ID_SEARCHDIALOG),
hwndViewer, SearchDlgProc, (LPARAM)lpVwrInfo);
if(iRet)
{
GetWindowRect(lpVwrInfo->hwndViewer, &rc);
lpVwrInfo->hwndResults = CreateDialog(ghModule,
MAKEINTRESOURCE(ID_RESULTSDIALOG),
lpVwrInfo->hwndViewer,
ResultsDlgProc);
if(lpVwrInfo->hwndResults == NULL)
{
TopicListDestroy(lpVwrInfo->htlResults);
HighlightDestroy(lpVwrInfo->hHighlight);
lpVwrInfo->htlResults = NULL;
lpVwrInfo->hHighlight = NULL;
ShowMessage(hwndViewer, KSERR_CANTCREATERESULTS,
MB_ICONEXCLAMATION);
}
}
}
/**************************************************************************
* ExecFullTextSearch
*
* Entry-point function for QuicKeys search interface. This function
* performs a search using the supplied query and displays a results
* dialog box.
*
* Register with: RegisterRoutine("katasrch","ExecFullTextSearch","USSS")
* Call with: ExecFullTextSearch(hwndApp, qchPath, "query text", "")
*
**************************************************************************/
void WINAPI ExecFullTextSearch(
DWORD dwHwndViewer, // LOWORD has the Viewer window handle
LPSTR lpszTitle, // Title filename
LPSTR lpszQuery, // Query text
LPSTR lpszUnused) // Unused (left for 1.0 compatibility)
{
LPVWRINFO lpVwrInfo;
HWND hwndViewer = LOWORD(dwHwndViewer);
QUERYERR qerr;
int iRet;
RECT rc;
// Get the task data
lpVwrInfo = GetTaskData(GetCurrentTask());
if(lpVwrInfo == NULL)
{
ShowMessage(hwndViewer, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
return;
}
// Initialize the task-information structure
iRet = InitViewerInfo(lpVwrInfo, hwndViewer, lpszTitle);
if(iRet)
{
ShowMessage(hwndViewer, iRet, MB_ICONEXCLAMATION);
return;
}
iRet = DoSearch(lpVwrInfo, lpszQuery, NULL, &qerr,
IMPLICIT_OR | TL_QKEY);
if(iRet)
{
ShowMessage(hwndViewer, iRet, MB_ICONEXCLAMATION);
return;
}
GetWindowRect(lpVwrInfo->hwndViewer, &rc);
lpVwrInfo->hwndResults = CreateDialog(ghModule,
MAKEINTRESOURCE(ID_RESULTSDIALOG),
lpVwrInfo->hwndViewer,
ResultsDlgProc);
if(lpVwrInfo->hwndResults == NULL)
{
TopicListDestroy(lpVwrInfo->htlResults);
HighlightDestroy(lpVwrInfo->hHighlight);
lpVwrInfo->htlResults = NULL;
lpVwrInfo->hHighlight = NULL;
ShowMessage(hwndViewer, KSERR_CANTCREATERESULTS, MB_ICONEXCLAMATION);
}
}
/***************************************************************************
* LDLLHandler
*
* Provides the message interface between the DLL and the title.
*
***************************************************************************/
LONG WINAPI LDLLHandler(
UINT msg, // Message to process
LPARAM lParam1, // Message-dependent information
LPARAM lParam2) // Message-dependent information
{
LPVWRINFO lpVwrInfo;
switch(msg)
{
case DW_WHATMSG:
return DC_INITTERM | DC_JUMP | DC_CONFIG;
case DW_INIT:
// Get the current task handle. Allocate a block of instance
// data and store in a table indexed by this task handle.
lpVwrInfo = AddTask(GetCurrentTask());
// A FALSE return value cancels the loading of the DLL.
return lpVwrInfo != NULL;
case DW_CHGFILE:
// Ignore this message if this is a secondary window jump
if(lParam2)
return TRUE;
// Get the current task handle and retrieve the instance data
// for this task.
lpVwrInfo = GetTaskData(GetCurrentTask());
if(lpVwrInfo == NULL)
{
ShowMessage(NULL, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
return TRUE;
}
// Close the results window, if it's displayed. Results window will
// clean up the topic list and highlight information.
if(lpVwrInfo->hwndResults)
{
DestroyWindow(lpVwrInfo->hwndResults);
lpVwrInfo->hwndResults = NULL;
}
if(lpVwrInfo->htitle)
{
TitleClose(lpVwrInfo->htitle);
lpVwrInfo->htitle = NULL;
}
lstrcpy(lpVwrInfo->szMVB, (LPSTR)lParam1);
return TRUE;
case DW_TERM:
// Get the current task handle and retrieve the instance data
// for this task.
lpVwrInfo = GetTaskData(GetCurrentTask());
if(lpVwrInfo == NULL)
{
ShowMessage(NULL, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
return TRUE;
}
// If the DLL has an open title associated with this instance,
// close the title.
if(lpVwrInfo->htitle)
TitleClose(lpVwrInfo->htitle);
if(lpVwrInfo->hfontDlg)
DeleteObject(lpVwrInfo->hfontDlg);
if(lpVwrInfo->vwrHelp)
VwrQuit(lpVwrInfo->vwrHelp);
DeleteTask(GetCurrentTask());
return TRUE;
case DW_STARTJUMP:
case DW_ENDJUMP:
return TRUE;
}
}
/*************************************************************************
* DoSearch
*
* Workhorse function that submits the specified query. This function
* also destroys an existing Results dialog box prior to recording the
* new topic list and highlight data.
*
* Returns zero if successful; otherwise, returns an error code.
*************************************************************************/
int DoSearch(
LPVWRINFO lpVwrInfo,
LPSTR lpszQuery,
HTLIST htlDomain,
LPQUERYERR lpqerr,
WORD wFlags)
{
HCURSOR hcurOld;
HTLIST htl;
HANDLE hHL;
hcurOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
// Submit the query
htl = TopicListFromQuery(lpVwrInfo->htitle, wFlags, lpszQuery,
htlDomain, NULL, NULL,
&hHL, lpqerr);
if(hcurOld)
SetCursor(hcurOld);
if(htl == NULL)
return KSERR_QUERY;
lpVwrInfo->lNumTopics = TopicListLength(htl);
if(lpVwrInfo->lNumTopics <= 0)
{
TopicListDestroy(htl);
HighlightDestroy(hHL);
return KSERR_NOTOPICSFOUND;
}
if(lpVwrInfo->hwndResults)
{
DestroyWindow(lpVwrInfo->hwndResults);
}
lpVwrInfo->htlResults = htl;
lpVwrInfo->hHighlight = hHL;
return 0;
}
/************************************************************************
* ShowMessage: Load a string resource and display in a message box.
*
************************************************************************/
void ShowMessage(HWND hWnd, int nMessage, int nIcon)
{
char szMessage[512];
MessageBeep(nIcon);
if(LoadString(ghModule, nMessage, szMessage, 511) > 0)
{
MessageBox(hWnd, szMessage, szTitleSearch,
MB_OK | nIcon);
}
else
{
MessageBox(hWnd, "Unspecified error.", szTitleSearch,
MB_OK | nIcon);
}
}
/************************************************************************
* ShowQueryError: Displays Viewer query error message and positions
* combo-box cursor at position of error.
*
************************************************************************/
void ShowQueryError(HWND hWnd, LPQUERYERR lpqerr)
{
static char*szGenericMsg = "Error in search text at specified position.";
char szResStr[256];
int nRes;
switch(lpqerr->iError)
{
case ERR_NULLQUERY:
case ERR_EXPECTEDTERM:
case ERR_MISSQUOTE:
case ERR_MISSLPAREN:
case ERR_MISSRPAREN:
case ERR_TOODEEP:
case ERR_TOOMANYTOKENS:
case ERR_BADVALUE:
case ERR_BADRANGEOP:
case ERR_ALL_WILD:
case ERR_NON_LAST_WILD:
nRes = KSERR_QUERYBASE + lpqerr->iError;
if(LoadString(ghModule, nRes, szResStr, 255))
break;
// If LoadString failed for our custom messages, fall through and
// try to load the Viewer message.
default:
if(QueryGetErrorMessage(lpqerr->iError, szResStr, 255) == 0)
{
lstrcpy(szResStr, szGenericMsg);
}
break;
}
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(hWnd, szResStr, szTitleSearch,
MB_OK | MB_ICONEXCLAMATION);
SetFocus(hWnd);
SendMessage(hWnd, EM_SETSEL, 1, MAKELONG(lpqerr->iStart, lpqerr->iStart));
}
/**********************************************************************
* DisplaySearchHelp
*
* Submits a jump command to display search help in a secondary
* window. To display a secondary window that doesn't interfere with
* the functioning of the Search dialog box, we use a second, hidden
* Viewer instance. This means the secondary window is independent of
* the Viewer instance displaying the karate topics. Each instance of
* the karate title uses its own hidden Viewer instance to display
* Help.
*
* Note: When this function is first called for a given Viewer session,
* it starts the hidden Viewer instance and stores the VWR identifier
* in the variable referenced by lpvwrHelp.
*
**********************************************************************/
int DisplaySearchHelp(
VWR FAR *lpvwrHelp, // Pointer to a VWR identifier
LPSTR lpszMVB) // Name of help file
{
char szCommand[64];
if(LoadString(ghModule, ID_HELPCOMMAND, szCommand, 63) == 0)
return KSERR_MEMORY;
if(*lpvwrHelp == NULL)
{
*lpvwrHelp = VwrCommand(NULL, lpszMVB, szCommand, cmdoptHIDE);
if(*lpvwrHelp)
return 0;
else
return KSERR_NOVWR;
}
else
{
if(VwrCommand(*lpvwrHelp, NULL, szCommand, cmdoptNONE) == *lpvwrHelp)
return 0;
else
return KSERR_NOVWR;
}
}
/**********************************************************************
* LoadWheel
*
* Loads the phrases of a word wheel into a combo box.
*
**********************************************************************/
int LoadWheel(
HWND hwndCB, // Window handle of combo box
LPSTR lpszMVB, // Filename of title file
LPSTR lpszWheel) // Word wheel name
{
int i; // Index into word wheel
LONG lLen; // Length of word wheel
HWHEEL hWheel; // Handle to word wheel
char szPhrase[129]; // Buffer to hold word-wheel phrase
int iRet = 0; // Assume success
// Try to open the specified word wheel
hWheel = WordWheelOpen(lpszMVB, lpszWheel);
if(hWheel == NULL)
{
return KSERR_CANTOPENWORDWHEEL;
}
// Retrieve each phrase and add it to the combo box
for(i = 0, lLen = WordWheelLength(hWheel); i < lLen; i++)
{
if(WordWheelLookup(hWheel, i, szPhrase, 128))
{
iRet = KSERR_CANTLOADWORDWHEELPHRASE;
break;
}
SendMessage(hwndCB, CB_ADDSTRING, 0, (LPARAM)(LPSTR)szPhrase);
}
// Close the word wheel
WordWheelClose(hWheel);
return iRet;
}
/**********************************************************************
* LoadGroup
*
* Creates a merged topic list consisting of the topics in the
* list specified in htlDomain and the topics in the topic group
* specified by lpszGroup.
*
**********************************************************************/
HTLIST LoadGroup(
HTITLE hTitle, // Title containing topic group
HTLIST htlDomain, // Domain list to merge with group
LPSTR lpszGroup, // Name of group to load
int nOp, // Merge operation
BOOL bDelete) // Delete original domain list?
{
HTLIST htlGrp; // To receive loaded group
HTLIST htlMerge; // To receive merged group
// Load topic group. If load fails, return error.
htlGrp = TopicListLoad(hTitle, lpszGroup);
if(htlGrp == NULL)
{
return NULL;
}
// Don't need to merge if domain list is NULL
if(htlDomain == NULL)
{
return htlGrp;
}
// Merge domain list with group
htlMerge = TopicListCombine(nOp, htlDomain, htlGrp, FALSE);
// Delete component groups
if(bDelete)
TopicListDestroy(htlDomain);
TopicListDestroy(htlGrp);
// Return merged list (NULL if TopicListCombine failed)
return htlMerge;
}
/**********************************************************************
* BuildDomain
*
* Creates a topic list containing all the groups indicated in the
* dialog box fields.
*
**********************************************************************/
int BuildDomain(
HWND hwnd, // Handle to query dialog
LPVWRINFO lpVwrInfo, // Viewer instance information
HTLIST FAR *lphtl) // Where to store the domain list
{
char szGroup[20];
HTLIST htlRet;
int i, iRet;
*lphtl = NULL;
if(!IsDlgButtonChecked(hwnd, ID_GROUPSEL))
return 0;
for(i = ID_CUONGNHU; i <= ID_WINGTSUN; i++)
{
if(SendDlgItemMessage(hwnd, i, BM_GETCHECK, 0, 0L))
{
if(LoadString(ghModule, i, szGroup, 19) == 0)
{
iRet = KSERR_MEMORY;
goto ErrorCleanup;
}
htlRet = LoadGroup(lpVwrInfo->htitle, *lphtl, szGroup,
TL_OR, FALSE);
if(htlRet == NULL)
{
iRet = KSERR_CANTOPENTOPICGROUP;
goto ErrorCleanup;
}
*lphtl = htlRet;
}
}
if(*lphtl == NULL)
return KSERR_NOGROUPSSELECTED;
else
return 0;
ErrorCleanup:
if(*lphtl)
TopicListDestroy(*lphtl);
return iRet;
}
/**********************************************************************
* BuildQuery
*
* Builds a query string using the information entered in the search
* dialog box fields.
*
**********************************************************************/
int BuildQuery(
HWND hwnd, // Handle to query dialog
LPVWRINFO lpVwrInfo, // Viewer instance information
LPSTR lpszQuery) // Where to store the query text
{
char szLevel[QUERY_LENGTH+1];
char szText[QUERY_LENGTH+1];
int iQueryLen, iLevelLen;
// Check to see if a query was entered.
iQueryLen = GetWindowTextLength(GetDlgItem(hwnd, ID_QUERY));
iLevelLen = GetWindowTextLength(GetDlgItem(hwnd, ID_RANK));
// The user can enter a query, a level (rank), or both.
if((iQueryLen == 0) && (iLevelLen == 0))
return KSERR_NOQUERY;
if((iQueryLen > QUERY_LENGTH) || (iLevelLen == QUERY_LENGTH))
return KSERR_QUERYLENGTH;
// Build the query
GetDlgItemText(hwnd, ID_RANK, szLevel, QUERY_LENGTH);
GetDlgItemText(hwnd, ID_QUERY, szText, QUERY_LENGTH);
if(*szLevel)
wsprintf(lpszQuery, "%s VFLD %d %s VFLD 0",
(LPSTR)szText, WHEEL_LEVEL, (LPSTR)szLevel);
else
lstrcpy(lpszQuery, szText);
OutputDebugString(lpszQuery); OutputDebugString("\r\n");
return 0;
}
/**************************************************************************
* DoQueryDialogSearch
*
* Performs a search from the query dialog box. Collects necessary
* information from the query dialog and then calls DoSearch to submit
* the query and display the results window.
**************************************************************************/
int DoQueryDialogSearch(
HWND hwnd, // Window handle of query dialog
LPVWRINFO lpVwrInfo, // Viewer task info
LPQUERYERR lpqerr) // Pointer to query error structure
{
char szQuery[QUERY_LENGTH*2+1];
HTLIST htlDomain;
int iRet;
iRet = BuildQuery(hwnd, lpVwrInfo, szQuery);
if(iRet)
return iRet;
iRet = BuildDomain(hwnd, lpVwrInfo, &htlDomain);
if(iRet)
return iRet;
iRet = DoSearch(lpVwrInfo, szQuery, htlDomain, lpqerr, IMPLICIT_AND);
if(htlDomain)
TopicListDestroy(htlDomain);
return iRet;
}
/**************************************************************************
* InitDialogControls
*
* Loads word-wheel info for the Rank combo box, sets various check boxes,
* changes fonts for controls.
**************************************************************************/
int InitDialogControls(
HWND hwnd, // Window handle of query dialog
LPVWRINFO lpVwrInfo) // Viewer task info
{
int iRet, i;
iRet = LoadWheel(GetDlgItem(hwnd, ID_RANK), lpVwrInfo->szMVB, "level");
if(iRet)
return iRet;
SendDlgItemMessage(hwnd, ID_SHOTOKAN, BM_SETCHECK, 1, 0L);
SendDlgItemMessage(hwnd, ID_CUONGNHU, BM_SETCHECK, 1, 0L);
SendDlgItemMessage(hwnd, ID_WINGTSUN, BM_SETCHECK, 1, 0L);
CheckRadioButton(hwnd, ID_GROUPANY, ID_GROUPSEL, ID_GROUPANY);
SendMessage(hwnd, WM_COMMAND, ID_GROUPANY,
MAKELONG(GetDlgItem(hwnd, ID_GROUPANY), BN_CLICKED));
if(lpVwrInfo->hfontDlg)
{
for(i = ID_TEXT1; i <= ID_WINGTSUN; i++)
SendDlgItemMessage(hwnd, i, WM_SETFONT,
(WPARAM)lpVwrInfo->hfontDlg, TRUE);
SendDlgItemMessage(hwnd, IDOK, WM_SETFONT,
(WPARAM)lpVwrInfo->hfontDlg, TRUE);
SendDlgItemMessage(hwnd, IDCANCEL, WM_SETFONT,
(WPARAM)lpVwrInfo->hfontDlg, TRUE);
SendDlgItemMessage(hwnd, ID_HELP, WM_SETFONT,
(WPARAM)lpVwrInfo->hfontDlg, TRUE);
}
return 0;
}
/**************************************************************************
* SearchDlgProc
*
* Dialog-box procedure for search dialog box.
**************************************************************************/
BOOL CALLBACK SearchDlgProc(
HWND hwnd, // Window handle
UINT msg, // Message
WPARAM wParam, // Message parameter
LPARAM lParam) // Message parameter
{
LPVWRINFO lpVwrInfo;
QUERYERR qerr;
int iRet;
switch(msg)
{
case WM_INITDIALOG:
// Get the Viewer instance data passed to lParam
lpVwrInfo = (LPVWRINFO)lParam;
if(lpVwrInfo == NULL)
{
ShowMessage(hwnd, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
EndDialog(hwnd, 0);
return TRUE;
}
// Initialize the dialog-box controls
iRet = InitDialogControls(hwnd, lpVwrInfo);
if(iRet)
{
EndDialog(hwnd, 0);
}
return TRUE;
case WM_COMMAND:
switch(wParam)
{
case IDOK:
// Get Viewer instance data for current task
lpVwrInfo = GetTaskData(GetCurrentTask());
if(lpVwrInfo == NULL)
{
ShowMessage(hwnd, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
break;
}
// Perform the search
iRet = DoQueryDialogSearch(hwnd, lpVwrInfo, &qerr);
switch(iRet)
{
case 0:
EndDialog(hwnd, 1);
break;
case KSERR_QUERY:
ShowQueryError(GetDlgItem(hwnd, ID_QUERY), &qerr);
break;
default:
ShowMessage(hwnd, iRet, MB_ICONEXCLAMATION);
break;
}
break;
case IDCANCEL:
EndDialog(hwnd, 0);
break;
case ID_HELP:
// Get Viewer instance data for current task
lpVwrInfo = GetTaskData(GetCurrentTask());
if(lpVwrInfo == NULL)
{
ShowMessage(hwnd, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
EndDialog(hwnd, 0);
break;
}
// Display the help window for search
iRet = DisplaySearchHelp(&lpVwrInfo->vwrHelp, lpVwrInfo->szMVB);
if(iRet)
ShowMessage(hwnd, iRet, MB_ICONEXCLAMATION);
break;
case ID_GROUPANY:
case ID_GROUPSEL:
if(HIWORD(lParam) != BN_CLICKED)
break;
EnableWindow(GetDlgItem(hwnd, ID_SHOTOKAN), wParam == ID_GROUPSEL);
EnableWindow(GetDlgItem(hwnd, ID_CUONGNHU), wParam == ID_GROUPSEL);
EnableWindow(GetDlgItem(hwnd, ID_WINGTSUN), wParam == ID_GROUPSEL);
break;
}
break;
case WM_CLOSE:
EndDialog(hwnd,0);
break;
}
return FALSE;
}